<?php
require_once 'Zend/View/Interface.php'; 
require_once 'Smarty/View/Exception.php'; 
 
/**
 * @see http://smarty.php.net/
 */ 
require_once 'Smarty/libs/Smarty.class.php'; 
 
/**
 * Wrapper class up Smarty
 */ 
 
class Smarty_View implements Zend_View_Interface 
{ 
    /**
     * Smarty instance
     *
     * @var Smarty
     */ 
    protected $_smarty; 
 
    /**
     * base path
     *
     * @var string
     */ 
    protected $_basePath; 
 
    /**
     * path names in properties => path relative to the base path
     *
     * @var array
     */ 
    protected $_pathDef; 
 
    /**
     * cache id
     *
     * @var string
     */ 
    protected $_cacheId; 
 
    /**
     * Sets the properties and instantiates the Smarty
     *
     * @param array $properties properties of Smarty (name => value)
     * @return void
     * @throws Smarty_View_Exception
     */ 
    public function __construct($properties = array()) 
    { 
        if (class_exists('Smarty')) { 
            $this->_smarty   = new Smarty; 
            $this->_basePath = null; 
            $this->_pathDef  = array( 
                'template_dir' => 'templates', 
                'compile_dir'  => 'templates_c', 
                'config_dir'   => 'configs', 
                'cache_dir'    => 'cache', 
                'plugins_dir'  => '', 
                'secure_dir'   => '', 
                'trusted_dir'  => '', 
                ); 
            $this->_cacheId  = null; 
			$this->setBasePath('application/views/scripts/');
            $this->setProperties($properties); 
            return; 
        } 
 
        throw new Smarty_View_Exception('You can not use Smarty'); 
    } 
 
    /**
     * Set the properties of Smarty
     *
     * @param array $properties properties of Smarty (name => value)
     * @return void
     */ 
    public function setProperties($properties = array()) 
    { 
        foreach ($properties as $key => $value) { 
            $this->setProperty($key, $value); 
        } 
    } 
 
    /**
     * Retrieve the properties of Smarty
     *
     * @return array
     */ 
    public function getProperties() 
    { 
        $ret = array(); 
 
        foreach ($this->_smarty as $key => $value) { 
            if($key{0} !== '_'){ 
                $ret[$key] = $value; 
            } 
        } 
 
        return $ret; 
    } 
 
    /**
     * Set property of Smarty
     *
     * @param string $key property name
     * @param mixed $value property value
     * @return Zend_View_Wrapper_Smarty
     * @throws Smarty_View_Exception
     */ 
    public function setProperty($key, $value) 
    { 
        if(!property_exists($this->_smarty, $key)){ 
            throw new Smarty_View_Exception('Invalid property '.$key.' provided'); 
        } 
 
        if(key_exists($key, $this->_pathDef)){ 
            if (!is_readable($value)) { 
                throw new Smarty_View_Exception('Invalid path property '.$key.' provided'); 
            } 
        } 
 
        if(is_array($this->_smarty->$key)){ 
            $this->_smarty->{$key}[] = $value; 
        }else{ 
            $this->_smarty->$key = $value; 
        } 
 
        return $this; 
    } 
 
    /**
     * Retrieve property of Smarty
     *
     * @param string $key property name
     * @return string|array
     * @throws Smarty_View_Exception
     */ 
    public function getProperty($key) 
    { 
        if(property_exists($this->_smarty, $key)){ 
            return $this->_smarty->$key; 
        } 
 
        throw new Smarty_View_Exception('Invalid property '.$key.' provided'); 
    } 
 
    /**
     * Alias to getSmarty
     *
     * @see getSmarty
     * @return Smarty
     */ 
    public function getEngine() 
    { 
        return $this->getSmarty(); 
    } 
    /**
     * Return the Smarty instance
     *
     * @return Smarty
     */ 
    public function getSmarty() 
    { 
        return $this->_smarty; 
    } 
 
    /**
     * Alias to setTemplatePath
     *
     * @see setTemplatePath
     * @param string $path path
     * @return Zend_View_Wrapper_Smarty
     */ 
    public function setScriptPath($path) 
    { 
        return $this->setTemplatePath($path); 
    } 
 
    /**
     * Alias to getTemplatePath
     *
     * @see getTemplatePath
     * @return string
     */ 
    public function getScriptPath() 
    { 
        return $this->getTemplatePath(); 
    } 
 
    /**
     * Retrieve the current template path
     *
     * @see getTemplatePath
     * @return array
     */ 
    public function getScriptPaths() 
    { 
        return array($this->getTemplatePath()); 
    } 
 
    /**
     * Set the path as base path
     *
     * @param string $path base path
     * @param string $prefix unused
     * @return Zend_View_Wrapper_Smarty
     * @throws Smarty_View_Exception
     */ 
    public function setBasePath($path, $prefix = 'Zend_View') 
    { 
        if (is_readable($path)) { 
            $this->_basePath = $path; 
 
            $this->setTemplatePath( 
                    $path.$this->_pathDef['template_dir']); 
            $this->setCompilePath( 
                    $path.$this->_pathDef['compile_dir']); 
            $this->setCachePath( 
                    $path.$this->_pathDef['cache_dir']); 
            $this->setConfigPath( 
                    $path.$this->_pathDef['config_dir']); 
            return $this; 
        } 
 
        throw new Smarty_View_Exception('Invalid base path provided'); 
    } 
 
    /**
     * Retrieve the current base path
     *
     * @return string
     */ 
    public function getBasePath() 
    { 
        return $this->_basePath; 
    } 
 
    /**
     * Alias to setBasePath
     *
     * @see setBasePath
     * @param string $path base path
     * @param string $prefix unused
     * @return Zend_View_Wrapper_Smarty
     */ 
    public function addBasePath($path, $prefix = 'Zend_View') 
    { 
        return $this->setBasePath($path, $prefix); 
    } 
 
    /**
     * Set the path to the path relative to the base path
     *
     * @param string $name path name in properties of Smarty
     * @param string $path path relative to the pase path
     * @return Zend_View_Wrapper_Smarty
     * @throws Smarty_View_Exception
     */ 
    public function setRelativePath($name, $path) 
    { 
        if(key_exists($name, $this->_pathDef)){ 
            $this->_pathDef['$name'] = $path; 
            return $this; 
        } 
 
        throw new Smarty_View_Exception('Invalid path name provided'); 
    } 
 
    /**
     * Retrieve the path to the path relative to the base path
     *
     * @param string $name path name in properties of Smarty
     * @return string
     * @throws Smarty_View_Exception
     */ 
    public function getRelativePath($name) 
    { 
        if(key_exists($name, $this->_pathDef)){ 
            return $this->_pathDef['$name']; 
        } 
 
        throw new Smarty_View_Exception('Invalid path name provided'); 
    } 
 
    /**
     * Assign a variable to the template
     *
     * @param string $key variable name.
     * @param mixed $val variable value.
     * @return void
     */ 
    public function __set($key, $val) 
    { 
        $this->_smarty->assign($key, $val); 
    } 
 
    /**
     * Retrieve an assigned variable
     *
     * @param string $key variable name.
     * @return mixed variable value.
     */ 
    public function __get($key) 
    { 
        return $this->_smarty->get_template_vars($key); 
    } 
 
    /**
     * Allows testing with empty() and isset() to work
     *
     * @param string $key variable name.
     * @return boolean
     */ 
    public function __isset($key) 
    { 
        return (null !== $this->_smarty->get_template_vars($key)); 
    } 
 
    /**
     * Allows unset() on object properties to work
     *
     * @param string $key variable name.
     * @return void
     */ 
    public function __unset($key) 
    { 
        $this->_smarty->clear_assign($key); 
    } 
 
    /**
     * Assign variables to the template
     *
     * Allows setting a specific key to the specified value, OR passing an array
     * of key => value pairs to set en masse.
     *
     * @see __set()
     * @param string|array $spec The assignment strategy to use (key or array of key
     * => value pairs)
     * @param mixed $value (Optional) If assigning a named variable, use this
     * as the value.
     * @return void
     */ 
    public function assign($spec, $value = null) 
    { 
        if (is_array($spec)) { 
            $this->_smarty->assign($spec); 
            return; 
        } 
 
        $this->_smarty->assign($spec, $value); 
    } 
 
    /**
     * Assign variables to the template by refference
     *
     * @see assign
     * @param string|array $spec The assignment strategy to use (key or array of key
     * => value pairs)
     * @param mixed $value (Optional) If assigning a named variable, use this
     * as the value.
     * @return void
     */ 
    public function assignByRef(&$spec, &$value = null) 
    { 
        if (is_array($spec)) { 
            $this->_smarty->assign($spec); 
            return; 
        } 
 
        $this->_smarty->assign_by_ref($spec, $value); 
    } 
 
    /**
     * Clear all assigned variables
     *
     * @return void
     */ 
    public function clearVars() 
    { 
        $this->_smarty->clear_all_assign(); 
    } 
 
	/**
     * Processes a template and display.
     *
     * @param string $name template to process.
     * @return void.
     */ 
    public function display($name) 
    { 
        $this->_smarty->display( 
                            $name, 
                            $this->_cacheId, 
                            $this->_smarty->compile_id 
                            ); 
    } 
	
	/**
     * Processes a template and display.
     *
     * @param string $name template to process.
     * @return void.
     */ 
    public function render($name) 
    { 
        $this->_smarty->display( 
                            $name, 
                            $this->_cacheId, 
                            $this->_smarty->compile_id 
                            ); 
    } 
 
    /**
     * Processes a template and returns the output string.
     *
     * @param string $name template to process.
     * @return string
     */ 
    public function output($name) 
    { 
        return $this->_smarty->fetch($name, 
                                     $this->_cacheId, 
                                     $this->_smarty->compile_id 
                                     ); 
    }
	/**
     * Processes a template and returns the output string.
     *
     * @param string $name template to process.
     * @return string
     */ 
    public function fetch($name) 
    { 
        return $this->_smarty->fetch($name, 
                                     $this->_cacheId, 
                                     $this->_smarty->compile_id 
                                     ); 
    }  
 
    /**
     * Set the path to the template path
     *
     * @param string $path template path.
     * @return Zend_View_Wrapper_Smarty
     * @throws Smarty_View_Exception
     */ 
    public function setTemplatePath($path) 
    { 
        if (is_readable($path)) { 
            $this->_smarty->template_dir = $path; 
            return $this; 
        } 
 
        throw new Smarty_View_Exception('Invalid template path provided'); 
    } 
 
    /**
     * Retrieve the current template path
     *
     * @return string
     */ 
    public function getTemplatePath() 
    { 
        return $this->_smarty->template_dir; 
    } 
 
    /**
     * Set the path to the compile path
     *
     * @param string $path compile path.
     * @return Zend_View_Wrapper_Smarty
     * @throws Smarty_View_Exception
     */ 
    public function setCompilePath($path) 
    { 
        if (is_readable($path)) { 
            $this->_smarty->compile_dir = $path; 
            return $this; 
        } 
 
        throw new Smarty_View_Exception('Invalid compile path provided'); 
    } 
 
    /**
     * Retrieve the current compiled template path
     *
     * @return string
     */ 
    public function getCompilePath() 
    { 
        return $this->_smarty->compile_dir; 
    } 
 
    /**
     * Set the path to the cache path
     *
     * @param string $path cache path.
     * @return Zend_View_Wrapper_Smarty
     * @throws Smarty_View_Exception
     */ 
    public function setCachePath($path) 
    { 
        if (is_readable($path)) { 
            $this->_smarty->cache_dir = $path; 
            return $this; 
        } 
 
        throw new Smarty_View_Exception('Invalid cache path provided'); 
    } 
 
    /**
     * Retrieve the current cache path
     *
     * @return string
     */ 
    public function getCachePath() 
    { 
        return $this->_smarty->cache_dir; 
    } 
 
    /**
     * Set the path to the configuration path
     *
     * @param string $path configuration path
     * @return Zend_View_Wrapper_Smarty
     * @throws Smarty_View_Exception
     */ 
    public function setConfigPath($path) 
    { 
        if (is_readable($path)) { 
            $this->_smarty->config_dir = $path; 
            return $this; 
        } 
 
        throw new Smarty_View_Exception('Invalid configuration path provided'); 
    } 
 
    /**
     * Retrieve the current configuration path
     *
     * @return string
     */ 
    public function getConfigPath() 
    { 
        return $this->_smarty->config_dir; 
    } 
 
    /**
     * Set the type to the cache type
     *
     * @param integer $type cache type
     * @return Zend_View_Wrapper_Smarty
     */ 
    public function setCacheType($type) 
    { 
        $this->_smarty->caching = $type; 
        return $this; 
    } 
 
    /**
     * Retrieve the current cache type
     *
     * @return integer
     */ 
    public function getCacheType() 
    { 
        return $this->_smarty->caching; 
    } 
 
    /**
     * Set the time to the cache time
     *
     * @param integer $time cache time
     * @return Zend_View_Wrapper_Smarty
     */ 
    public function setCacheTime($time) 
    { 
        $this->_smarty->cache_lifetime = $time; 
        return $this; 
    } 
 
    /**
     * Retrieve the current cache time
     *
     * @return integer
     */ 
    public function getCacheTime() 
    { 
        return $this->_smarty->cache_lifetime; 
    } 
 
    /**
     * Set the id to the cache id
     *
     * @param string $id cache id
     * @return Zend_View_Wrapper_Smarty
     */ 
    public function setCacheId($id) 
    { 
        $this->_cacheId = $id; 
        return $this; 
    } 
 
    /**
     * Retrieve the current cache id
     *
     * @return string
     */ 
    public function getCacheId() 
    { 
        return $this->_cacheId; 
    } 
 
    /**
     * Set the id to the compile id
     *
     * @param string $id compile id
     * @return Zend_View_Wrapper_Smarty
     */ 
    public function setCompileId($id) 
    { 
        $this->_smarty->compile_id = $id; 
        return $this; 
    } 
 
    /**
     * Retrieve the current compile id
     *
     * @return string
     */ 
    public function getCompileId() 
    { 
        return $this->_smarty->compile_id; 
    } 
 
    /**
     * Retrieve whether or not the template is cached
     *
     * @param string $name template name
     * @return string|false
     */ 
    public function isCached($name) 
    { 
        return $this->_smarty->is_cached( 
                                $name, 
                                $this->_cacheId, 
                                $this->_smarty->compile_id 
                                ); 
    } 
 
    /**
     * Clear cached template
     *
     * @param string $name template name
     * @param integer $time expiration time (second)
     * @return boolean
     */ 
    public function clearCachedTemplate($name, $time = null) 
    { 
        return $this->_smarty->clear_cache( 
                        $name, 
                        $this->_cacheId, 
                        $this->_smarty->compile_id, 
                        $time 
                        ); 
    } 
 
    /**
     * Clear compiled template
     *
     * @param string $name template name
     * @param integer $time expiration time (seconds)
     * @return boolean
     */ 
    public function clearCompiledTemplate($name, $time = null) 
    { 
        return $this->_smarty->clear_compiled_tpl( 
                                $name, 
                                $this->_smarty->compile_id, 
                                $time 
                                ); 
    } 
 
    /**
     * Clear all cached templates
     *
     * @param integer $time expiration time (seconds)
     * @return boolean
     */ 
    public function clearAllCachedTemplates($time = null) 
    { 
        return $this->_smarty->clear_all_cache($time); 
    } 
} 